<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>多功能文本编辑器</title>
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
    <style>
        * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
        }
        
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background: #f5f5f5;
            height: 100vh;
            overflow: hidden;
        }
        
        .editor-container {
            display: flex;
            flex-direction: column;
            height: 100vh;
            background: white;
            box-shadow: 0 0 20px rgba(0,0,0,0.1);
        }
        
        .editor-header {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 15px 20px;
            display: flex;
            justify-content: space-between;
            align-items: center;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
        }
        
        .editor-title {
            font-size: 1.5em;
            font-weight: 600;
        }
        
        .editor-status {
            display: flex;
            gap: 20px;
            font-size: 0.9em;
            opacity: 0.9;
        }
        
        .status-item {
            display: flex;
            align-items: center;
            gap: 5px;
        }
        
        .status-indicator {
            width: 8px;
            height: 8px;
            border-radius: 50%;
            background: #4CAF50;
        }
        
        .status-indicator.saving {
            background: #FF9800;
            animation: pulse 1s infinite;
        }
        
        @keyframes pulse {
            0%, 100% { opacity: 1; }
            50% { opacity: 0.5; }
        }
        
        .toolbar {
            background: #fafafa;
            border-bottom: 1px solid #e0e0e0;
            padding: 10px 20px;
            display: flex;
            gap: 15px;
            align-items: center;
            flex-wrap: wrap;
        }
        
        .toolbar-group {
            display: flex;
            gap: 5px;
            align-items: center;
            padding-right: 15px;
            border-right: 1px solid #e0e0e0;
        }
        
        .toolbar-group:last-child {
            border-right: none;
        }
        
        .toolbar-btn {
            padding: 8px 12px;
            border: 1px solid #ddd;
            background: white;
            border-radius: 4px;
            cursor: pointer;
            font-size: 14px;
            transition: all 0.2s ease;
            display: flex;
            align-items: center;
            gap: 5px;
        }
        
        .toolbar-btn:hover {
            background: #f0f0f0;
            border-color: #ccc;
        }
        
        .toolbar-btn.active {
            background: #667eea;
            color: white;
            border-color: #667eea;
        }
        
        .toolbar-select {
            padding: 6px 10px;
            border: 1px solid #ddd;
            border-radius: 4px;
            background: white;
            font-size: 14px;
            cursor: pointer;
        }
        
        .toolbar-input {
            padding: 6px 10px;
            border: 1px solid #ddd;
            border-radius: 4px;
            width: 60px;
            text-align: center;
            font-size: 14px;
        }
        
        .editor-main {
            display: flex;
            flex: 1;
            overflow: hidden;
        }
        
        .editor-sidebar {
            width: 250px;
            background: #f9f9f9;
            border-right: 1px solid #e0e0e0;
            display: flex;
            flex-direction: column;
        }
        
        .sidebar-section {
            padding: 15px;
            border-bottom: 1px solid #e0e0e0;
        }
        
        .sidebar-title {
            font-weight: 600;
            margin-bottom: 10px;
            color: #333;
        }
        
        .file-list {
            max-height: 200px;
            overflow-y: auto;
        }
        
        .file-item {
            padding: 8px 12px;
            cursor: pointer;
            border-radius: 4px;
            margin-bottom: 2px;
            display: flex;
            justify-content: space-between;
            align-items: center;
            transition: background 0.2s ease;
        }
        
        .file-item:hover {
            background: #e3f2fd;
        }
        
        .file-item.active {
            background: #667eea;
            color: white;
        }
        
        .file-actions {
            display: flex;
            gap: 5px;
        }
        
        .file-action {
            padding: 2px 6px;
            border: none;
            background: transparent;
            cursor: pointer;
            border-radius: 2px;
            font-size: 12px;
        }
        
        .file-action:hover {
            background: rgba(255,255,255,0.2);
        }
        
        .collaboration-panel {
            flex: 1;
        }
        
        .user-list {
            display: flex;
            flex-direction: column;
            gap: 8px;
        }
        
        .user-item {
            display: flex;
            align-items: center;
            gap: 10px;
            padding: 8px;
            background: white;
            border-radius: 6px;
            box-shadow: 0 1px 3px rgba(0,0,0,0.1);
        }
        
        .user-avatar {
            width: 32px;
            height: 32px;
            border-radius: 50%;
            background: linear-gradient(45deg, #667eea, #764ba2);
            display: flex;
            align-items: center;
            justify-content: center;
            color: white;
            font-weight: 600;
            font-size: 14px;
        }
        
        .user-info {
            flex: 1;
        }
        
        .user-name {
            font-weight: 500;
            font-size: 14px;
        }
        
        .user-status {
            font-size: 12px;
            color: #666;
        }
        
        .editor-content {
            flex: 1;
            display: flex;
            flex-direction: column;
            position: relative;
        }
        
        .editor-tabs {
            display: flex;
            background: #f5f5f5;
            border-bottom: 1px solid #e0e0e0;
            overflow-x: auto;
        }
        
        .editor-tab {
            padding: 12px 20px;
            background: #f5f5f5;
            border-right: 1px solid #e0e0e0;
            cursor: pointer;
            display: flex;
            align-items: center;
            gap: 8px;
            min-width: 150px;
            transition: background 0.2s ease;
        }
        
        .editor-tab:hover {
            background: #eeeeee;
        }
        
        .editor-tab.active {
            background: white;
            border-bottom: 2px solid #667eea;
        }
        
        .tab-close {
            margin-left: auto;
            padding: 2px 6px;
            border: none;
            background: transparent;
            cursor: pointer;
            border-radius: 2px;
            font-size: 16px;
            line-height: 1;
        }
        
        .tab-close:hover {
            background: rgba(0,0,0,0.1);
        }
        
        .editor-workspace {
            flex: 1;
            position: relative;
            overflow: hidden;
        }
        
        .editor-textarea {
            width: 100%;
            height: 100%;
            border: none;
            outline: none;
            padding: 20px;
            font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
            font-size: 14px;
            line-height: 1.6;
            resize: none;
            background: white;
        }
        
        .editor-footer {
            background: #f5f5f5;
            border-top: 1px solid #e0e0e0;
            padding: 8px 20px;
            display: flex;
            justify-content: space-between;
            align-items: center;
            font-size: 12px;
            color: #666;
        }
        
        .footer-left {
            display: flex;
            gap: 20px;
        }
        
        .footer-right {
            display: flex;
            gap: 20px;
        }
        
        .context-menu {
            position: fixed;
            background: white;
            border: 1px solid #ddd;
            border-radius: 6px;
            box-shadow: 0 4px 12px rgba(0,0,0,0.15);
            z-index: 1000;
            min-width: 150px;
            padding: 5px 0;
        }
        
        .context-menu-item {
            padding: 8px 15px;
            cursor: pointer;
            display: flex;
            align-items: center;
            gap: 10px;
            font-size: 14px;
            transition: background 0.2s ease;
        }
        
        .context-menu-item:hover {
            background: #f0f0f0;
        }
        
        .context-menu-item.disabled {
            opacity: 0.5;
            cursor: not-allowed;
        }
        
        .context-menu-divider {
            height: 1px;
            background: #e0e0e0;
            margin: 5px 0;
        }
        
        .shortcut {
            margin-left: auto;
            font-size: 12px;
            color: #999;
        }
        
        .modal {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0,0,0,0.5);
            display: flex;
            align-items: center;
            justify-content: center;
            z-index: 2000;
        }
        
        .modal-content {
            background: white;
            border-radius: 8px;
            padding: 20px;
            max-width: 500px;
            width: 90%;
            max-height: 80vh;
            overflow-y: auto;
        }
        
        .modal-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 20px;
            padding-bottom: 10px;
            border-bottom: 1px solid #e0e0e0;
        }
        
        .modal-title {
            font-size: 1.2em;
            font-weight: 600;
        }
        
        .modal-close {
            background: none;
            border: none;
            font-size: 24px;
            cursor: pointer;
            padding: 0;
            width: 30px;
            height: 30px;
            display: flex;
            align-items: center;
            justify-content: center;
            border-radius: 50%;
        }
        
        .modal-close:hover {
            background: #f0f0f0;
        }
        
        .modal-body {
            margin-bottom: 20px;
        }
        
        .form-group {
            margin-bottom: 15px;
        }
        
        .form-label {
            display: block;
            margin-bottom: 5px;
            font-weight: 500;
        }
        
        .form-input {
            width: 100%;
            padding: 8px 12px;
            border: 1px solid #ddd;
            border-radius: 4px;
            font-size: 14px;
        }
        
        .form-input:focus {
            outline: none;
            border-color: #667eea;
            box-shadow: 0 0 0 2px rgba(102, 126, 234, 0.2);
        }
        
        .modal-actions {
            display: flex;
            gap: 10px;
            justify-content: flex-end;
        }
        
        .btn {
            padding: 8px 16px;
            border: 1px solid #ddd;
            border-radius: 4px;
            cursor: pointer;
            font-size: 14px;
            transition: all 0.2s ease;
        }
        
        .btn-primary {
            background: #667eea;
            color: white;
            border-color: #667eea;
        }
        
        .btn-primary:hover {
            background: #5a6fd8;
        }
        
        .btn-secondary {
            background: white;
            color: #333;
        }
        
        .btn-secondary:hover {
            background: #f0f0f0;
        }
        
        .toast {
            position: fixed;
            top: 20px;
            right: 20px;
            background: #4CAF50;
            color: white;
            padding: 12px 20px;
            border-radius: 6px;
            box-shadow: 0 4px 12px rgba(0,0,0,0.15);
            z-index: 3000;
            animation: slideInRight 0.3s ease;
        }
        
        .toast.error {
            background: #f44336;
        }
        
        .toast.warning {
            background: #ff9800;
        }
        
        @keyframes slideInRight {
            from {
                opacity: 0;
                transform: translateX(100%);
            }
            to {
                opacity: 1;
                transform: translateX(0);
            }
        }
        
        .drag-overlay {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(102, 126, 234, 0.1);
            border: 2px dashed #667eea;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 1.2em;
            color: #667eea;
            font-weight: 600;
            z-index: 1000;
        }
        
        .search-replace {
            position: absolute;
            top: 10px;
            right: 10px;
            background: white;
            border: 1px solid #ddd;
            border-radius: 6px;
            padding: 15px;
            box-shadow: 0 4px 12px rgba(0,0,0,0.15);
            z-index: 500;
            min-width: 300px;
        }
        
        .search-input {
            width: 100%;
            padding: 6px 10px;
            border: 1px solid #ddd;
            border-radius: 4px;
            margin-bottom: 8px;
            font-size: 14px;
        }
        
        .search-actions {
            display: flex;
            gap: 5px;
            justify-content: flex-end;
        }
        
        .search-btn {
            padding: 4px 8px;
            border: 1px solid #ddd;
            background: white;
            border-radius: 3px;
            cursor: pointer;
            font-size: 12px;
        }
        
        .search-btn:hover {
            background: #f0f0f0;
        }
        
        .word-count {
            position: absolute;
            bottom: 10px;
            right: 10px;
            background: rgba(0,0,0,0.7);
            color: white;
            padding: 5px 10px;
            border-radius: 4px;
            font-size: 12px;
            pointer-events: none;
        }
    </style>
</head>
<body>
    <div id="app">
        <div class="editor-container">
            <!-- 编辑器头部 -->
            <div class="editor-header">
                <div class="editor-title">多功能文本编辑器</div>
                <div class="editor-status">
                    <div class="status-item">
                        <div class="status-indicator" :class="{ saving: isSaving }"></div>
                        <span>{{ saveStatus }}</span>
                    </div>
                    <div class="status-item">
                        <span>👥 {{ collaborators.length }} 人在线</span>
                    </div>
                    <div class="status-item">
                        <span>{{ currentTime }}</span>
                    </div>
                </div>
            </div>
            
            <!-- 工具栏 -->
            <div class="toolbar">
                <div class="toolbar-group">
                    <button class="toolbar-btn" @click="newFile" title="新建文件 (Ctrl+N)">
                        📄 新建
                    </button>
                    <button class="toolbar-btn" @click="openFile" title="打开文件 (Ctrl+O)">
                        📁 打开
                    </button>
                    <button class="toolbar-btn" @click="saveFile" title="保存文件 (Ctrl+S)">
                        💾 保存
                    </button>
                    <button class="toolbar-btn" @click="saveAsFile" title="另存为 (Ctrl+Shift+S)">
                        📋 另存为
                    </button>
                </div>
                
                <div class="toolbar-group">
                    <button class="toolbar-btn" @click="undo" :disabled="!canUndo" title="撤销 (Ctrl+Z)">
                        ↶ 撤销
                    </button>
                    <button class="toolbar-btn" @click="redo" :disabled="!canRedo" title="重做 (Ctrl+Y)">
                        ↷ 重做
                    </button>
                </div>
                
                <div class="toolbar-group">
                    <button class="toolbar-btn" @click="cut" title="剪切 (Ctrl+X)">
                        ✂️ 剪切
                    </button>
                    <button class="toolbar-btn" @click="copy" title="复制 (Ctrl+C)">
                        📋 复制
                    </button>
                    <button class="toolbar-btn" @click="paste" title="粘贴 (Ctrl+V)">
                        📌 粘贴
                    </button>
                </div>
                
                <div class="toolbar-group">
                    <button class="toolbar-btn" @click="toggleSearch" title="查找替换 (Ctrl+F)">
                        🔍 查找
                    </button>
                    <button class="toolbar-btn" @click="selectAll" title="全选 (Ctrl+A)">
                        📝 全选
                    </button>
                </div>
                
                <div class="toolbar-group">
                    <select class="toolbar-select" v-model="fontSize" @change="updateFontSize">
                        <option value="12">12px</option>
                        <option value="14">14px</option>
                        <option value="16">16px</option>
                        <option value="18">18px</option>
                        <option value="20">20px</option>
                        <option value="24">24px</option>
                    </select>
                    
                    <select class="toolbar-select" v-model="fontFamily" @change="updateFontFamily">
                        <option value="Consolas">Consolas</option>
                        <option value="Monaco">Monaco</option>
                        <option value="Courier New">Courier New</option>
                        <option value="Arial">Arial</option>
                        <option value="Times New Roman">Times New Roman</option>
                    </select>
                </div>
                
                <div class="toolbar-group">
                    <button class="toolbar-btn" :class="{ active: wordWrap }" @click="toggleWordWrap" title="自动换行">
                        📄 换行
                    </button>
                    <button class="toolbar-btn" @click="toggleFullscreen" title="全屏模式 (F11)">
                        🔲 全屏
                    </button>
                </div>
            </div>
            
            <!-- 主要内容区域 -->
            <div class="editor-main">
                <!-- 侧边栏 -->
                <div class="editor-sidebar" v-show="showSidebar">
                    <!-- 文件列表 -->
                    <div class="sidebar-section">
                        <div class="sidebar-title">文件</div>
                        <div class="file-list">
                            <div 
                                v-for="(file, index) in files" 
                                :key="file.id"
                                class="file-item"
                                :class="{ active: file.id === currentFileId }"
                                @click="switchFile(file.id)"
                            >
                                <span>{{ file.name }}</span>
                                <div class="file-actions">
                                    <button class="file-action" @click.stop="renameFile(file.id)" title="重命名">
                                        ✏️
                                    </button>
                                    <button class="file-action" @click.stop="deleteFile(file.id)" title="删除">
                                        🗑️
                                    </button>
                                </div>
                            </div>
                        </div>
                        <button class="toolbar-btn" @click="newFile" style="width: 100%; margin-top: 10px;">
                            ➕ 新建文件
                        </button>
                    </div>
                    
                    <!-- 协作面板 -->
                    <div class="sidebar-section collaboration-panel">
                        <div class="sidebar-title">协作者</div>
                        <div class="user-list">
                            <div v-for="user in collaborators" :key="user.id" class="user-item">
                                <div class="user-avatar">{{ user.name.charAt(0) }}</div>
                                <div class="user-info">
                                    <div class="user-name">{{ user.name }}</div>
                                    <div class="user-status">{{ user.status }}</div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
                
                <!-- 编辑器内容 -->
                <div class="editor-content">
                    <!-- 标签页 -->
                    <div class="editor-tabs" v-show="files.length > 1">
                        <div 
                            v-for="file in files" 
                            :key="file.id"
                            class="editor-tab"
                            :class="{ active: file.id === currentFileId }"
                            @click="switchFile(file.id)"
                        >
                            <span>{{ file.name }}</span>
                            <span v-if="file.modified">*</span>
                            <button class="tab-close" @click.stop="closeFile(file.id)" title="关闭">
                                ×
                            </button>
                        </div>
                    </div>
                    
                    <!-- 编辑器工作区 -->
                    <div class="editor-workspace" 
                         @drop="handleDrop" 
                         @dragover.prevent 
                         @dragenter.prevent
                         @contextmenu.prevent="showContextMenu">
                        
                        <!-- 拖拽覆盖层 -->
                        <div v-if="isDragging" class="drag-overlay">
                            📁 拖拽文件到这里打开
                        </div>
                        
                        <!-- 文本编辑区 -->
                        <textarea 
                            ref="textarea"
                            class="editor-textarea"
                            v-model="currentFile.content"
                            @input="handleInput"
                            @keydown="handleKeydown"
                            @select="updateSelection"
                            @scroll="handleScroll"
                            :style="{
                                fontSize: fontSize + 'px',
                                fontFamily: fontFamily,
                                whiteSpace: wordWrap ? 'pre-wrap' : 'pre'
                            }"
                            placeholder="开始输入您的内容..."
                            spellcheck="false"
                        ></textarea>
                        
                        <!-- 查找替换面板 -->
                        <div v-if="showSearchPanel" class="search-replace">
                            <input 
                                v-model="searchText" 
                                class="search-input" 
                                placeholder="查找内容"
                                @keydown.enter="findNext"
                                @keydown.escape="toggleSearch"
                            >
                            <input 
                                v-model="replaceText" 
                                class="search-input" 
                                placeholder="替换为"
                                @keydown.enter="replaceNext"
                                @keydown.escape="toggleSearch"
                            >
                            <div class="search-actions">
                                <button class="search-btn" @click="findPrevious">上一个</button>
                                <button class="search-btn" @click="findNext">下一个</button>
                                <button class="search-btn" @click="replaceNext">替换</button>
                                <button class="search-btn" @click="replaceAll">全部替换</button>
                                <button class="search-btn" @click="toggleSearch">关闭</button>
                            </div>
                        </div>
                        
                        <!-- 字数统计 -->
                        <div class="word-count" v-if="showWordCount">
                            字符: {{ wordCount.characters }} | 单词: {{ wordCount.words }} | 行: {{ wordCount.lines }}
                        </div>
                    </div>
                </div>
            </div>
            
            <!-- 状态栏 -->
            <div class="editor-footer">
                <div class="footer-left">
                    <span>行 {{ cursorPosition.line }}, 列 {{ cursorPosition.column }}</span>
                    <span>选中 {{ selectionLength }} 个字符</span>
                    <span>编码: UTF-8</span>
                </div>
                <div class="footer-right">
                    <span>{{ currentFile.language || 'Plain Text' }}</span>
                    <span @click="showSidebar = !showSidebar" style="cursor: pointer;">
                        {{ showSidebar ? '隐藏' : '显示' }}侧边栏
                    </span>
                </div>
            </div>
        </div>
        
        <!-- 右键菜单 -->
        <div v-if="contextMenu.show" class="context-menu" :style="{ left: contextMenu.x + 'px', top: contextMenu.y + 'px' }">
            <div class="context-menu-item" @click="undo" :class="{ disabled: !canUndo }">
                <span>撤销</span>
                <span class="shortcut">Ctrl+Z</span>
            </div>
            <div class="context-menu-item" @click="redo" :class="{ disabled: !canRedo }">
                <span>重做</span>
                <span class="shortcut">Ctrl+Y</span>
            </div>
            <div class="context-menu-divider"></div>
            <div class="context-menu-item" @click="cut">
                <span>剪切</span>
                <span class="shortcut">Ctrl+X</span>
            </div>
            <div class="context-menu-item" @click="copy">
                <span>复制</span>
                <span class="shortcut">Ctrl+C</span>
            </div>
            <div class="context-menu-item" @click="paste">
                <span>粘贴</span>
                <span class="shortcut">Ctrl+V</span>
            </div>
            <div class="context-menu-divider"></div>
            <div class="context-menu-item" @click="selectAll">
                <span>全选</span>
                <span class="shortcut">Ctrl+A</span>
            </div>
            <div class="context-menu-item" @click="toggleSearch">
                <span>查找替换</span>
                <span class="shortcut">Ctrl+F</span>
            </div>
        </div>
        
        <!-- 模态框 -->
        <div v-if="modal.show" class="modal" @click.self="closeModal">
            <div class="modal-content">
                <div class="modal-header">
                    <div class="modal-title">{{ modal.title }}</div>
                    <button class="modal-close" @click="closeModal">×</button>
                </div>
                <div class="modal-body">
                    <div v-if="modal.type === 'rename'" class="form-group">
                        <label class="form-label">文件名:</label>
                        <input 
                            v-model="modal.data.newName" 
                            class="form-input" 
                            @keydown.enter="confirmModal"
                            @keydown.escape="closeModal"
                            ref="modalInput"
                        >
                    </div>
                    <div v-else-if="modal.type === 'confirm'">
                        <p>{{ modal.message }}</p>
                    </div>
                </div>
                <div class="modal-actions">
                    <button class="btn btn-secondary" @click="closeModal">取消</button>
                    <button class="btn btn-primary" @click="confirmModal">确定</button>
                </div>
            </div>
        </div>
        
        <!-- 提示消息 -->
        <div v-if="toast.show" class="toast" :class="toast.type">
            {{ toast.message }}
        </div>
    </div>
    
    <script>
        const { createApp, ref, reactive, computed, onMounted, onUnmounted, nextTick, watch } = Vue;
        
        createApp({
            setup() {
                // 基础状态
                const textarea = ref(null);
                const modalInput = ref(null);
                const showSidebar = ref(true);
                const showSearchPanel = ref(false);
                const showWordCount = ref(true);
                const isDragging = ref(false);
                const isSaving = ref(false);
                
                // 编辑器设置
                const fontSize = ref(14);
                const fontFamily = ref('Consolas');
                const wordWrap = ref(true);
                
                // 文件管理
                const files = ref([
                    {
                        id: 1,
                        name: '未命名文档.txt',
                        content: '欢迎使用多功能文本编辑器！\n\n这是一个功能丰富的文本编辑器，支持：\n- 多文件编辑\n- 键盘快捷键\n- 查找替换\n- 协作功能\n- 拖拽文件\n- 自动保存\n\n开始您的创作吧！',
                        modified: false,
                        language: 'Text',
                        history: [],
                        historyIndex: -1
                    }
                ]);
                const currentFileId = ref(1);
                const nextFileId = ref(2);
                
                // 当前文件
                const currentFile = computed(() => {
                    return files.value.find(f => f.id === currentFileId.value) || files.value[0];
                });
                
                // 历史记录
                const canUndo = computed(() => {
                    return currentFile.value && currentFile.value.historyIndex > 0;
                });
                
                const canRedo = computed(() => {
                    return currentFile.value && currentFile.value.historyIndex < currentFile.value.history.length - 1;
                });
                
                // 光标位置
                const cursorPosition = ref({ line: 1, column: 1 });
                const selectionLength = ref(0);
                
                // 搜索替换
                const searchText = ref('');
                const replaceText = ref('');
                const searchResults = ref([]);
                const currentSearchIndex = ref(-1);
                
                // 字数统计
                const wordCount = computed(() => {
                    const content = currentFile.value?.content || '';
                    const characters = content.length;
                    const words = content.trim() ? content.trim().split(/\s+/).length : 0;
                    const lines = content.split('\n').length;
                    return { characters, words, lines };
                });
                
                // 协作者
                const collaborators = ref([
                    { id: 1, name: '张三', status: '正在编辑' },
                    { id: 2, name: '李四', status: '在线' },
                    { id: 3, name: '王五', status: '5分钟前活跃' }
                ]);
                
                // 当前时间
                const currentTime = ref('');
                
                // 保存状态
                const saveStatus = computed(() => {
                    if (isSaving.value) return '保存中...';
                    if (currentFile.value?.modified) return '未保存';
                    return '已保存';
                });
                
                // 右键菜单
                const contextMenu = reactive({
                    show: false,
                    x: 0,
                    y: 0
                });
                
                // 模态框
                const modal = reactive({
                    show: false,
                    type: '',
                    title: '',
                    message: '',
                    data: {},
                    callback: null
                });
                
                // 提示消息
                const toast = reactive({
                    show: false,
                    type: 'success',
                    message: ''
                });
                
                // 防抖函数
                const debounce = (func, delay) => {
                    let timeoutId;
                    return (...args) => {
                        clearTimeout(timeoutId);
                        timeoutId = setTimeout(() => func.apply(this, args), delay);
                    };
                };
                
                // 节流函数
                const throttle = (func, delay) => {
                    let lastCall = 0;
                    return (...args) => {
                        const now = Date.now();
                        if (now - lastCall >= delay) {
                            lastCall = now;
                            func.apply(this, args);
                        }
                    };
                };
                
                // 更新时间
                const updateTime = () => {
                    const now = new Date();
                    currentTime.value = now.toLocaleTimeString();
                };
                
                // 显示提示消息
                const showToast = (message, type = 'success') => {
                    toast.message = message;
                    toast.type = type;
                    toast.show = true;
                    setTimeout(() => {
                        toast.show = false;
                    }, 3000);
                };
                
                // 保存历史记录
                const saveHistory = () => {
                    if (!currentFile.value) return;
                    
                    const file = currentFile.value;
                    file.historyIndex++;
                    file.history = file.history.slice(0, file.historyIndex);
                    file.history.push(file.content);
                    
                    // 限制历史记录数量
                    if (file.history.length > 50) {
                        file.history.shift();
                        file.historyIndex--;
                    }
                };
                
                // 文件操作
                const newFile = () => {
                    const newFile = {
                        id: nextFileId.value++,
                        name: `未命名文档${nextFileId.value - 1}.txt`,
                        content: '',
                        modified: false,
                        language: 'Text',
                        history: [''],
                        historyIndex: 0
                    };
                    files.value.push(newFile);
                    currentFileId.value = newFile.id;
                    showToast('新建文件成功');
                };
                
                const openFile = () => {
                    const input = document.createElement('input');
                    input.type = 'file';
                    input.accept = '.txt,.md,.js,.html,.css,.json';
                    input.onchange = (e) => {
                        const file = e.target.files[0];
                        if (file) {
                            const reader = new FileReader();
                            reader.onload = (e) => {
                                const newFile = {
                                    id: nextFileId.value++,
                                    name: file.name,
                                    content: e.target.result,
                                    modified: false,
                                    language: getLanguageFromExtension(file.name),
                                    history: [e.target.result],
                                    historyIndex: 0
                                };
                                files.value.push(newFile);
                                currentFileId.value = newFile.id;
                                showToast(`打开文件 ${file.name} 成功`);
                            };
                            reader.readAsText(file);
                        }
                    };
                    input.click();
                };
                
                const saveFile = () => {
                    if (!currentFile.value) return;
                    
                    isSaving.value = true;
                    
                    // 模拟保存延迟
                    setTimeout(() => {
                        const blob = new Blob([currentFile.value.content], { type: 'text/plain' });
                        const url = URL.createObjectURL(blob);
                        const a = document.createElement('a');
                        a.href = url;
                        a.download = currentFile.value.name;
                        a.click();
                        URL.revokeObjectURL(url);
                        
                        currentFile.value.modified = false;
                        isSaving.value = false;
                        showToast('文件保存成功');
                    }, 500);
                };
                
                const saveAsFile = () => {
                    modal.show = true;
                    modal.type = 'rename';
                    modal.title = '另存为';
                    modal.data = { newName: currentFile.value.name };
                    modal.callback = (newName) => {
                        if (newName && newName.trim()) {
                            currentFile.value.name = newName.trim();
                            saveFile();
                        }
                    };
                    
                    nextTick(() => {
                        if (modalInput.value) {
                            modalInput.value.focus();
                            modalInput.value.select();
                        }
                    });
                };
                
                const switchFile = (fileId) => {
                    currentFileId.value = fileId;
                };
                
                const closeFile = (fileId) => {
                    const fileIndex = files.value.findIndex(f => f.id === fileId);
                    if (fileIndex === -1) return;
                    
                    const file = files.value[fileIndex];
                    if (file.modified) {
                        modal.show = true;
                        modal.type = 'confirm';
                        modal.title = '确认关闭';
                        modal.message = `文件 "${file.name}" 有未保存的更改，确定要关闭吗？`;
                        modal.callback = () => {
                            files.value.splice(fileIndex, 1);
                            if (currentFileId.value === fileId) {
                                currentFileId.value = files.value.length > 0 ? files.value[0].id : null;
                            }
                            if (files.value.length === 0) {
                                newFile();
                            }
                        };
                    } else {
                        files.value.splice(fileIndex, 1);
                        if (currentFileId.value === fileId) {
                            currentFileId.value = files.value.length > 0 ? files.value[0].id : null;
                        }
                        if (files.value.length === 0) {
                            newFile();
                        }
                    }
                };
                
                const renameFile = (fileId) => {
                    const file = files.value.find(f => f.id === fileId);
                    if (!file) return;
                    
                    modal.show = true;
                    modal.type = 'rename';
                    modal.title = '重命名文件';
                    modal.data = { newName: file.name };
                    modal.callback = (newName) => {
                        if (newName && newName.trim()) {
                            file.name = newName.trim();
                            file.language = getLanguageFromExtension(newName);
                            showToast('文件重命名成功');
                        }
                    };
                    
                    nextTick(() => {
                        if (modalInput.value) {
                            modalInput.value.focus();
                            modalInput.value.select();
                        }
                    });
                };
                
                const deleteFile = (fileId) => {
                    const file = files.value.find(f => f.id === fileId);
                    if (!file) return;
                    
                    modal.show = true;
                    modal.type = 'confirm';
                    modal.title = '确认删除';
                    modal.message = `确定要删除文件 "${file.name}" 吗？此操作不可撤销。`;
                    modal.callback = () => {
                        const fileIndex = files.value.findIndex(f => f.id === fileId);
                        files.value.splice(fileIndex, 1);
                        if (currentFileId.value === fileId) {
                            currentFileId.value = files.value.length > 0 ? files.value[0].id : null;
                        }
                        if (files.value.length === 0) {
                            newFile();
                        }
                        showToast('文件删除成功');
                    };
                };
                
                // 编辑操作
                const undo = () => {
                    if (!canUndo.value) return;
                    
                    const file = currentFile.value;
                    file.historyIndex--;
                    file.content = file.history[file.historyIndex];
                    file.modified = true;
                };
                
                const redo = () => {
                    if (!canRedo.value) return;
                    
                    const file = currentFile.value;
                    file.historyIndex++;
                    file.content = file.history[file.historyIndex];
                    file.modified = true;
                };
                
                const cut = () => {
                    if (textarea.value) {
                        const start = textarea.value.selectionStart;
                        const end = textarea.value.selectionEnd;
                        const selectedText = currentFile.value.content.substring(start, end);
                        
                        if (selectedText) {
                            navigator.clipboard.writeText(selectedText);
                            currentFile.value.content = currentFile.value.content.substring(0, start) + 
                                                      currentFile.value.content.substring(end);
                            currentFile.value.modified = true;
                            saveHistory();
                            showToast('文本已剪切');
                        }
                    }
                };
                
                const copy = () => {
                    if (textarea.value) {
                        const start = textarea.value.selectionStart;
                        const end = textarea.value.selectionEnd;
                        const selectedText = currentFile.value.content.substring(start, end);
                        
                        if (selectedText) {
                            navigator.clipboard.writeText(selectedText);
                            showToast('文本已复制');
                        }
                    }
                };
                
                const paste = async () => {
                    try {
                        const text = await navigator.clipboard.readText();
                        if (textarea.value) {
                            const start = textarea.value.selectionStart;
                            const end = textarea.value.selectionEnd;
                            
                            currentFile.value.content = currentFile.value.content.substring(0, start) + 
                                                       text + 
                                                       currentFile.value.content.substring(end);
                            currentFile.value.modified = true;
                            saveHistory();
                            
                            nextTick(() => {
                                textarea.value.selectionStart = textarea.value.selectionEnd = start + text.length;
                                textarea.value.focus();
                            });
                            
                            showToast('文本已粘贴');
                        }
                    } catch (err) {
                        showToast('粘贴失败', 'error');
                    }
                };
                
                const selectAll = () => {
                    if (textarea.value) {
                        textarea.value.select();
                        updateSelection();
                    }
                };
                
                // 查找替换
                const toggleSearch = () => {
                    showSearchPanel.value = !showSearchPanel.value;
                    if (showSearchPanel.value) {
                        nextTick(() => {
                            const searchInput = document.querySelector('.search-input');
                            if (searchInput) searchInput.focus();
                        });
                    }
                };
                
                const findNext = () => {
                    if (!searchText.value) return;
                    
                    const content = currentFile.value.content;
                    const currentPos = textarea.value.selectionEnd;
                    const index = content.indexOf(searchText.value, currentPos);
                    
                    if (index !== -1) {
                        textarea.value.selectionStart = index;
                        textarea.value.selectionEnd = index + searchText.value.length;
                        textarea.value.focus();
                        updateSelection();
                    } else {
                        // 从头开始查找
                        const firstIndex = content.indexOf(searchText.value);
                        if (firstIndex !== -1) {
                            textarea.value.selectionStart = firstIndex;
                            textarea.value.selectionEnd = firstIndex + searchText.value.length;
                            textarea.value.focus();
                            updateSelection();
                        } else {
                            showToast('未找到匹配内容', 'warning');
                        }
                    }
                };
                
                const findPrevious = () => {
                    if (!searchText.value) return;
                    
                    const content = currentFile.value.content;
                    const currentPos = textarea.value.selectionStart;
                    const index = content.lastIndexOf(searchText.value, currentPos - 1);
                    
                    if (index !== -1) {
                        textarea.value.selectionStart = index;
                        textarea.value.selectionEnd = index + searchText.value.length;
                        textarea.value.focus();
                        updateSelection();
                    } else {
                        // 从末尾开始查找
                        const lastIndex = content.lastIndexOf(searchText.value);
                        if (lastIndex !== -1) {
                            textarea.value.selectionStart = lastIndex;
                            textarea.value.selectionEnd = lastIndex + searchText.value.length;
                            textarea.value.focus();
                            updateSelection();
                        } else {
                            showToast('未找到匹配内容', 'warning');
                        }
                    }
                };
                
                const replaceNext = () => {
                    if (!searchText.value) return;
                    
                    const start = textarea.value.selectionStart;
                    const end = textarea.value.selectionEnd;
                    const selectedText = currentFile.value.content.substring(start, end);
                    
                    if (selectedText === searchText.value) {
                        currentFile.value.content = currentFile.value.content.substring(0, start) + 
                                                   replaceText.value + 
                                                   currentFile.value.content.substring(end);
                        currentFile.value.modified = true;
                        saveHistory();
                        
                        nextTick(() => {
                            textarea.value.selectionStart = start;
                            textarea.value.selectionEnd = start + replaceText.value.length;
                            findNext();
                        });
                    } else {
                        findNext();
                    }
                };
                
                const replaceAll = () => {
                    if (!searchText.value) return;
                    
                    const originalContent = currentFile.value.content;
                    const newContent = originalContent.replaceAll(searchText.value, replaceText.value);
                    
                    if (newContent !== originalContent) {
                        currentFile.value.content = newContent;
                        currentFile.value.modified = true;
                        saveHistory();
                        
                        const count = (originalContent.match(new RegExp(searchText.value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g')) || []).length;
                        showToast(`已替换 ${count} 处`);
                    } else {
                        showToast('未找到匹配内容', 'warning');
                    }
                };
                
                // 格式设置
                const updateFontSize = () => {
                    if (textarea.value) {
                        textarea.value.style.fontSize = fontSize.value + 'px';
                    }
                };
                
                const updateFontFamily = () => {
                    if (textarea.value) {
                        textarea.value.style.fontFamily = fontFamily.value;
                    }
                };
                
                const toggleWordWrap = () => {
                    wordWrap.value = !wordWrap.value;
                };
                
                const toggleFullscreen = () => {
                    if (!document.fullscreenElement) {
                        document.documentElement.requestFullscreen();
                    } else {
                        document.exitFullscreen();
                    }
                };
                
                // 事件处理
                const handleInput = debounce(() => {
                    if (currentFile.value) {
                        currentFile.value.modified = true;
                        saveHistory();
                    }
                }, 1000);
                
                const handleKeydown = (event) => {
                    // 阻止某些默认行为
                    if (event.ctrlKey) {
                        switch (event.key.toLowerCase()) {
                            case 'n':
                                event.preventDefault();
                                newFile();
                                break;
                            case 'o':
                                event.preventDefault();
                                openFile();
                                break;
                            case 's':
                                event.preventDefault();
                                if (event.shiftKey) {
                                    saveAsFile();
                                } else {
                                    saveFile();
                                }
                                break;
                            case 'z':
                                event.preventDefault();
                                if (event.shiftKey) {
                                    redo();
                                } else {
                                    undo();
                                }
                                break;
                            case 'y':
                                event.preventDefault();
                                redo();
                                break;
                            case 'f':
                                event.preventDefault();
                                toggleSearch();
                                break;
                            case 'a':
                                // 允许默认的全选行为
                                break;
                            case 'x':
                                // 允许默认的剪切行为，但添加提示
                                setTimeout(() => showToast('文本已剪切'), 100);
                                break;
                            case 'c':
                                // 允许默认的复制行为，但添加提示
                                setTimeout(() => showToast('文本已复制'), 100);
                                break;
                            case 'v':
                                // 允许默认的粘贴行为，但添加提示
                                setTimeout(() => showToast('文本已粘贴'), 100);
                                break;
                        }
                    }
                    
                    // Tab键处理
                    if (event.key === 'Tab') {
                        event.preventDefault();
                        const start = textarea.value.selectionStart;
                        const end = textarea.value.selectionEnd;
                        
                        currentFile.value.content = currentFile.value.content.substring(0, start) + 
                                                   '    ' + 
                                                   currentFile.value.content.substring(end);
                        
                        nextTick(() => {
                            textarea.value.selectionStart = textarea.value.selectionEnd = start + 4;
                        });
                    }
                    
                    // F11全屏
                    if (event.key === 'F11') {
                        event.preventDefault();
                        toggleFullscreen();
                    }
                    
                    // Escape关闭面板
                    if (event.key === 'Escape') {
                        if (showSearchPanel.value) {
                            showSearchPanel.value = false;
                        }
                        if (contextMenu.show) {
                            contextMenu.show = false;
                        }
                    }
                };
                
                const updateSelection = throttle(() => {
                    if (textarea.value) {
                        const start = textarea.value.selectionStart;
                        const end = textarea.value.selectionEnd;
                        const content = currentFile.value.content;
                        
                        // 计算光标位置
                        const beforeCursor = content.substring(0, start);
                        const lines = beforeCursor.split('\n');
                        cursorPosition.value = {
                            line: lines.length,
                            column: lines[lines.length - 1].length + 1
                        };
                        
                        // 计算选中长度
                        selectionLength.value = end - start;
                    }
                }, 100);
                
                const handleScroll = throttle(() => {
                    // 可以在这里添加滚动相关的逻辑
                }, 100);
                
                const handleDrop = (event) => {
                    event.preventDefault();
                    isDragging.value = false;
                    
                    const files = Array.from(event.dataTransfer.files);
                    files.forEach(file => {
                        if (file.type.startsWith('text/') || file.name.match(/\.(txt|md|js|html|css|json)$/i)) {
                            const reader = new FileReader();
                            reader.onload = (e) => {
                                const newFile = {
                                    id: nextFileId.value++,
                                    name: file.name,
                                    content: e.target.result,
                                    modified: false,
                                    language: getLanguageFromExtension(file.name),
                                    history: [e.target.result],
                                    historyIndex: 0
                                };
                                files.value.push(newFile);
                                currentFileId.value = newFile.id;
                                showToast(`打开文件 ${file.name} 成功`);
                            };
                            reader.readAsText(file);
                        } else {
                            showToast(`不支持的文件类型: ${file.name}`, 'error');
                        }
                    });
                };
                
                const showContextMenu = (event) => {
                    contextMenu.x = event.clientX;
                    contextMenu.y = event.clientY;
                    contextMenu.show = true;
                };
                
                // 模态框操作
                const closeModal = () => {
                    modal.show = false;
                    modal.callback = null;
                };
                
                const confirmModal = () => {
                    if (modal.callback) {
                        if (modal.type === 'rename') {
                            modal.callback(modal.data.newName);
                        } else {
                            modal.callback();
                        }
                    }
                    closeModal();
                };
                
                // 工具函数
                const getLanguageFromExtension = (filename) => {
                    const ext = filename.split('.').pop().toLowerCase();
                    const languageMap = {
                        'js': 'JavaScript',
                        'html': 'HTML',
                        'css': 'CSS',
                        'json': 'JSON',
                        'md': 'Markdown',
                        'txt': 'Text'
                    };
                    return languageMap[ext] || 'Text';
                };
                
                // 全局事件监听
                const handleGlobalClick = (event) => {
                    // 关闭右键菜单
                    if (contextMenu.show && !event.target.closest('.context-menu')) {
                        contextMenu.show = false;
                    }
                };
                
                const handleGlobalKeydown = (event) => {
                    // 全局快捷键
                    if (event.ctrlKey && event.shiftKey) {
                        switch (event.key.toLowerCase()) {
                            case 'p':
                                event.preventDefault();
                                // 命令面板（可扩展）
                                showToast('命令面板功能待开发', 'warning');
                                break;
                        }
                    }
                };
                
                const handleDragEnter = (event) => {
                    event.preventDefault();
                    isDragging.value = true;
                };
                
                const handleDragLeave = (event) => {
                    event.preventDefault();
                    if (!event.relatedTarget || !event.currentTarget.contains(event.relatedTarget)) {
                        isDragging.value = false;
                    }
                };
                
                // 自动保存
                const autoSave = debounce(() => {
                    if (currentFile.value && currentFile.value.modified) {
                        // 这里可以实现自动保存到本地存储
                        localStorage.setItem(`editor_file_${currentFile.value.id}`, JSON.stringify({
                            name: currentFile.value.name,
                            content: currentFile.value.content,
                            language: currentFile.value.language
                        }));
                    }
                }, 5000);
                
                // 监听文件内容变化
                watch(() => currentFile.value?.content, () => {
                    autoSave();
                }, { deep: true });
                
                // 生命周期
                onMounted(() => {
                    // 更新时间
                    updateTime();
                    setInterval(updateTime, 1000);
                    
                    // 添加全局事件监听
                    document.addEventListener('click', handleGlobalClick);
                    document.addEventListener('keydown', handleGlobalKeydown);
                    document.addEventListener('dragenter', handleDragEnter);
                    document.addEventListener('dragleave', handleDragLeave);
                    
                    // 聚焦到文本区域
                    nextTick(() => {
                        if (textarea.value) {
                            textarea.value.focus();
                        }
                    });
                    
                    // 从本地存储恢复文件
                    try {
                        const savedFiles = [];
                        for (let i = 0; i < localStorage.length; i++) {
                            const key = localStorage.key(i);
                            if (key && key.startsWith('editor_file_')) {
                                const fileData = JSON.parse(localStorage.getItem(key));
                                savedFiles.push({
                                    id: parseInt(key.replace('editor_file_', '')),
                                    name: fileData.name,
                                    content: fileData.content,
                                    language: fileData.language,
                                    modified: false,
                                    history: [fileData.content],
                                    historyIndex: 0
                                });
                            }
                        }
                        
                        if (savedFiles.length > 0) {
                            files.value = savedFiles;
                            currentFileId.value = savedFiles[0].id;
                            nextFileId.value = Math.max(...savedFiles.map(f => f.id)) + 1;
                        }
                    } catch (error) {
                        console.error('恢复文件失败:', error);
                    }
                });
                
                onUnmounted(() => {
                    // 移除全局事件监听
                    document.removeEventListener('click', handleGlobalClick);
                    document.removeEventListener('keydown', handleGlobalKeydown);
                    document.removeEventListener('dragenter', handleDragEnter);
                    document.removeEventListener('dragleave', handleDragLeave);
                });
                
                // 返回响应式数据和方法
                return {
                    // 引用
                    textarea,
                    modalInput,
                    
                    // 状态
                    showSidebar,
                    showSearchPanel,
                    showWordCount,
                    isDragging,
                    isSaving,
                    
                    // 设置
                    fontSize,
                    fontFamily,
                    wordWrap,
                    
                    // 文件
                    files,
                    currentFileId,
                    currentFile,
                    
                    // 历史
                    canUndo,
                    canRedo,
                    
                    // 光标和选择
                    cursorPosition,
                    selectionLength,
                    
                    // 搜索
                    searchText,
                    replaceText,
                    
                    // 统计
                    wordCount,
                    
                    // 协作
                    collaborators,
                    currentTime,
                    saveStatus,
                    
                    // UI组件
                    contextMenu,
                    modal,
                    toast,
                    
                    // 文件操作
                    newFile,
                    openFile,
                    saveFile,
                    saveAsFile,
                    switchFile,
                    closeFile,
                    renameFile,
                    deleteFile,
                    
                    // 编辑操作
                    undo,
                    redo,
                    cut,
                    copy,
                    paste,
                    selectAll,
                    
                    // 搜索替换
                    toggleSearch,
                    findNext,
                    findPrevious,
                    replaceNext,
                    replaceAll,
                    
                    // 格式设置
                    updateFontSize,
                    updateFontFamily,
                    toggleWordWrap,
                    toggleFullscreen,
                    
                    // 事件处理
                    handleInput,
                    handleKeydown,
                    updateSelection,
                    handleScroll,
                    handleDrop,
                    showContextMenu,
                    
                    // 模态框
                    closeModal,
                    confirmModal
                };
            }
        }).mount('#app');
    </script>
</body>
</html>